﻿#region copyright
//<copyright>
// Copyright(C) 2012 TrackerRealm Corporation
// This file is part of the open source project - Jazz. http://jazz.codeplex.com
// 
// Jazz is open software: you can redistribute it and/or modify it 
// under the terms of the GNU Affero General Public License (AGPL) as published by 
// the Free Software Foundation, version 3 of the License.
// 
// Jazz is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied warranty 
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
//  See the GNU Affero General Public License (AGPL) for more details.
// 
// You should have received a copy of the GNU General Public 
// License along with Jazz.  If not, see <http://www.gnu.org/licenses/>.
//
// REMOVAL OF THIS NOTICE IS VIOLATION OF THE COPYRIGHT. 
//</copyright>
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using TrackerRealm.Jazz.Common;
using C = TrackerRealm.Jazz.Common.JazzConstants;
using TrackerRealm.Jazz.Client.Custom;


namespace TrackerRealm.Jazz.Client
{
    /// <summary>
    /// 
    /// </summary>
    public class NexusConfigBase
    {
        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        public NexusConfigBase()
        {
            this.dataFlowEnabled = false;
            this.enhancedPersistence = false;
            this.bindUnits = new IjStorageUnit[0];
            this.ServerOperations = ServerOperations.Empty;
            this.Verbose = VerboseType.Off;
            this.VoidSafetyEnhanced = true;
            this.RoleCheckCollection = new string[0];
        }
        #endregion
        //
        // Instance members
        //
        #region BindUnits
        private IjStorageUnit[] bindUnits;
        /// <summary>
        /// BindUnits will automatically bound to the Client Nexus upon creation.
        /// <para>The 'PublicWorkspace' property will be ignored if this array contains a public workspace.</para>
        /// </summary>
        public IjStorageUnit[] BindUnits
        {
            get { return this.bindUnits; }
            set { this.bindUnits = value; }
        }
        #endregion
        #region LoginUser
        private jProfileBase loginProfile;
        private bool isLoginUserSpecified = false;
        /// <summary>
        /// <para>This is the profile that will be the logged in when the nexus is created.</para>
        /// <para>If no LoginProfile is specified a 'Guest' user, and default profile, will be created.</para>
        /// </summary>
        protected internal jProfileBase _LoginProfile
        {
            get { return this.loginProfile; }
            set
            {
                this.loginProfile = value;
                this.isLoginUserSpecified = true;
            }
        }
        #endregion
        #region IsLoginUserSpecified
        /// <summary>
        /// Returns true if a login user has been specified.
        /// </summary>
        internal bool IsLoginUserSpecified
        {
            get { return this.isLoginUserSpecified; }
        }
        #endregion
        #region DataFlowEnabled
        private bool dataFlowEnabled;
        /// <summary>
        /// <para>*** Feature Not Fully Implemented ***</para>
        /// DataFlow must be enabled to support Rules. Enabling Dataflow causes all workflow properties to be automatically updated.
        /// <para>When true requires that workflow fields and property types for collections and objects be observable 
        /// (supports the interface INotifyCollectionChanged and INotifyPropertChanged or a C5 style interface ICollectionsValue).</para>
        /// <para>Requires that 'Observable' attribute be used on Jazz object child classes.</para>
        /// </summary>
        public bool DataFlowEnabled
        {
            get { return this.dataFlowEnabled; }
            set { this.dataFlowEnabled = value; }
        }
        #endregion
        #region EnhancedPersistence
        private bool enhancedPersistence;
        /// <summary>
        /// <para>*** Feature Not Implemented ***</para>
        /// When true requires that workflow fields and property types for collections and objects be observable 
        /// (supports the interface INotifyCollectionChanged and INotifyPropertChanged or a C5 style interface ICollectionsValue)
        /// <para>A change collection will be created noting all the objects that have changed.</para>
        /// <para>Requires that 'Observable' attribute be used on Jazz object child classes.</para>
        /// </summary>
        public bool EnhancedPersistence
        {
            get { return this.enhancedPersistence; }
            set { throw new NotImplementedException(); }
        }
        #endregion
        #region ServerOperations
        /// <summary>
        /// <para>*** Feature Not Implemented ***</para>
        /// When set to an non Empty object provides server operations.
        /// <para>Server Operations provides features such as persistence.</para>
        /// </summary>
        public ServerOperations ServerOperations { get; set; }
        #endregion
        #region Verbose
        /// <summary>
        /// When this property is set to true then actions performed by Jazz will be written to the console.
        /// <para>This feature can only be activated when the 'Jazz' is compiled with the 'DEBUG' compiler constant defined.</para>
        /// <para>This feature is useful when debuging Jazz applications.</para>
        /// </summary>
        public VerboseType Verbose { get; set; }
        #endregion
        #region VoidSafety
        /// <summary>
        /// <para>*** Not fully Implemented *** Setting to false will have no effect currently.</para>
        /// When true empty Jazz objects are used instead of null to reduce
        /// the chances of getting 'NullReferenceException', 'ArgumentNullException', etc.
        /// <para>The default setting is true.</para>
        /// </summary>
        public bool VoidSafetyEnhanced { get; set; }
        #endregion
        #region PublicWorkspace
        /// <summary>
        /// 
        /// </summary>
        private Tuple<jWorkspaceBase, jWorkspaceBase> publicWorkspace;
        /// <summary>
        /// The public workspace object used by client nexus.  If the property '<see cref="BindUnits"/>' contains
        /// the public workspace this property is not used.
        /// <para>
        /// The first item must be public workspace and 2nd item of the must be the empty workspace.</para>
        /// <para>Note: This property will be ignored if the property 'StorageObjects' contains a public workspace.</para>
        /// </summary>
        protected internal Tuple<jWorkspaceBase, jWorkspaceBase> _PublicWorkspace
        {
            set
            {
                if (value == null || value.Item1 == null || (this.VoidSafetyEnhanced && value.Item2 == null))
                    throw new ArgumentNullException("Public Workspaces items may not be null. The empty workspace item may be null if 'VoidSafety' is set to false.");
                this.publicWorkspace = value;
            }
            get { return this.publicWorkspace; }
        }
        #endregion
        #region RoleCheck
        /// <summary>
        /// This feature insures that role names used in the 'GrantRole' attribute are properly spelled.
        /// <para>When role names provided in 'GrantRole' are checked, they are checked against actual Jazz Roles in the cache and
        /// the 'RoleCheckCollection'.</para>
        /// <para>The 'RoleCheckCollection' allows a designer create Jazz code using the 'GrantRole' attribute and have the role names checked
        /// before the actual roles are created.</para>
        /// <para>This configuration property is primarily used for development.</para>
        /// </summary>
        public IEnumerable<string> RoleCheckCollection
        {
            set;
            get;
        }
        #endregion
    }
}
